/*
 *    Copyright (c) 2018-2025, cloud All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: cloud
 */
package com.fuyao.cloud.asset.card.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.admin.api.entity.SysDept;
import com.fuyao.cloud.admin.api.entity.SysUser;
import com.fuyao.cloud.admin.api.feign.RemoteDeptService;
import com.fuyao.cloud.admin.api.feign.RemoteUserService;
import com.fuyao.cloud.asset.card.mapper.AssetAssetcardMapper;
import com.fuyao.cloud.asset.card.service.AssetAssetcardService;
import com.fuyao.cloud.asset.cardupdate.service.AssetAssetUpdateService;
import com.fuyao.cloud.asset.constant.AssetCardConstant;
import com.fuyao.cloud.asset.cti.service.AssetCtiService;
import com.fuyao.cloud.asset.dto.AssetCardCreateDTO;
import com.fuyao.cloud.asset.dto.AssetCardEditDTO;
import com.fuyao.cloud.asset.entity.*;
import com.fuyao.cloud.asset.entity.ac.AssetAc;
import com.fuyao.cloud.asset.entity.ac.AssetAcList;
import com.fuyao.cloud.asset.enums.CardStatusEnum;
import com.fuyao.cloud.asset.sau.service.AssetSauService;
import com.fuyao.cloud.asset.supplier.service.AssetSupplierService;
import com.fuyao.cloud.asset.vo.card.AssetCardDTO;
import com.fuyao.cloud.asset.vo.card.AssetCardExcelVO;
import com.fuyao.cloud.asset.vo.card.AssetCardImportVO;
import com.fuyao.cloud.common.core.constant.CommonConstants;
import com.fuyao.cloud.common.core.model.BaseEntity;
import com.fuyao.cloud.common.core.util.DictItemOption;
import com.fuyao.cloud.common.core.util.R;
import com.fuyao.cloud.common.data.datascope.DataScope;
import com.fuyao.cloud.common.data.resolver.DictItemResolver;
import com.fuyao.cloud.common.data.resolver.NumberResolver;
import com.fuyao.cloud.common.excel.vo.ErrorMessage;
import com.fuyao.cloud.common.security.service.CloudUser;
import com.fuyao.cloud.common.security.util.SecurityUtils;
import com.fuyao.cloud.space.position.service.RoomPositionService;
import com.fuyao.cloud.space.vo.PositionVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 资产信息管理
 *
 * @author liyue
 * @date 2021-11-18 18:44:56
 */
@Slf4j
@Service
@AllArgsConstructor
public class AssetAssetcardServiceImpl extends ServiceImpl<AssetAssetcardMapper, AssetCard> implements AssetAssetcardService {

    private AssetCtiService fyAssetCtiService;
    private RemoteDeptService remoteDeptService;
    private RemoteUserService remoteUserService;
    private AssetSupplierService supplierService;
    private AssetAssetUpdateService assetAssetUpdateService;
    private RoomPositionService positionService;
    private final AssetSauService fyAssetSauService;

    @Transactional
    @Override
    public boolean save(AssetCard entity) {
        setFieldValue(entity);
        return super.save(entity);
    }

    @Transactional
    @Override
    public boolean updateById(AssetCard entity) {
        AssetCard assetCardOld = this.getById(entity.getId());
        // 如果资产分类发生变化则需要重新生成number.
        if (!entity.getCtiId().equals(assetCardOld.getCtiId())) {
            AssetCti cti = fyAssetCtiService.getById(entity.getCtiId());
            entity.setNumber(getNumberStr(cti, entity));
        }
        // 保存修改记录
        assetAssetUpdateService.save(entity);
        setFieldValue(entity);
        return super.updateById(entity);
    }

    @Override
    public List<Tree<Long>> selectTree(QueryWrapper<AssetCard> query) {
        // 查询房屋信息
        List<AssetCard> cardList = this.baseMapper.selectList(query);
        // 查询数据权限内房屋信息
        List<Long> cardOwnIdList = this.baseMapper.selectListByScope(query, new DataScope()).stream()
                .map(BaseEntity::getDeptId).collect(Collectors.toList());

        // 权限内房屋信息
        List<TreeNode<Long>> collect = cardList.stream()
                .sorted(Comparator.comparingLong(AssetCard::getId)).map(card -> {
                    TreeNode<Long> treeNode = new TreeNode();
                    treeNode.setId(card.getId());
                    treeNode.setParentId(card.getParentId());
                    treeNode.setName(card.getName());
                    treeNode.setWeight(120);
                    // 有权限不返回标识
                    Map<String, Object> extra = new HashMap<>(8);
                    extra.put("isLock", !cardOwnIdList.contains(card.getDeptId()));
                    extra.put("createTime", card.getCreateTime());
                    extra.put("code", card.getContractId());

                    treeNode.setExtra(extra);
                    return treeNode;
                }).collect(Collectors.toList());
        return TreeUtil.build(collect, 0L);
    }

    @Override
    public List listAssetCard(QueryWrapper<AssetCard> query) {
        query.notIn("status", CardStatusEnum.OFFSET.getCode());
        // 查询字典信息
        Map<String, List<DictItemOption>> resultMap = DictItemResolver.getDictOptionResultMap(AssetCardConstant.ASSET_CARD_OPTIONS);

        List<AssetCard> assetCardList = this.baseMapper.selectListByScope(query, new DataScope());
        return assetCardList.stream().map(entity -> {
            AssetCardExcelVO exportVO = new AssetCardExcelVO();
            BeanUtils.copyProperties(entity, exportVO);
            exportVO.setStatus(DictItemResolver.getDictOptionLabel(resultMap.get(AssetCardConstant.ASSET_STATUS), entity.getStatus()));
            exportVO.setSource(DictItemResolver.getDictOptionLabel(resultMap.get(AssetCardConstant.ASSET_SOURCE), entity.getSource()));
            exportVO.setMonetaryUnit(DictItemResolver.getDictOptionLabel(resultMap.get(AssetCardConstant.ASSET_CURRENCY_UNIT), entity.getMonetaryUnit()));
            exportVO.setPurchaseMode(DictItemResolver.getDictOptionLabel(resultMap.get(AssetCardConstant.ASSET_PURCHASE_METHOD), entity.getPurchaseMode()));
            exportVO.setUsageOption(DictItemResolver.getDictOptionLabel(resultMap.get(AssetCardConstant.ASSET_HOW_USER), entity.getUsageOption()));
            return exportVO;
        }).collect(Collectors.toList());
    }

    @Override
    public R importAssetCard(List<AssetCardImportVO> excelVOList, BindingResult bindingResult) {
        // 通用校验获取失败的数据
        List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
        Set<String> errorMsg = new HashSet<>();
        if (CollUtil.isEmpty(excelVOList) && CollUtil.isEmpty(errorMessageList)) {
            assert errorMessageList != null;
            errorMsg.add("无数据导入!");
            errorMessageList.add(new ErrorMessage((long) (2), errorMsg));
            return R.failed(errorMessageList);
        }
        // 个性化校验逻辑
        List<SysDept> deptList = this.remoteDeptService.deptAll().getData();
        List<SysUser> userList = this.remoteUserService.userAll().getData();
        List<AssetSupplier> supplierList = supplierService.list();
        List<PositionVO> positionVOList = positionService.listPositionVO();
        Map<String, List<DictItemOption>> resultMap = DictItemResolver.getDictOptionResultMap(AssetCardConstant.ASSET_CARD_OPTIONS);
        List<AssetCti> ctiList = fyAssetCtiService.list();
        // 执行数据插入操作 组装 FyRoomRegional
        for (int i = 0; i < excelVOList.size(); i++) {
            AssetCardImportVO excel = excelVOList.get(i);
            // 拷贝属性
            AssetCard assetCard = new AssetCard();
            BeanUtils.copyProperties(excel, assetCard);
            // 处理类型不同无法属性拷贝
            assetCard.setOriginalAmount(new BigDecimal(excel.getOriginalAmount()));
            assetCard.setAmount(new BigDecimal(excel.getAmount()));
            assetCard.setUsefulLife(new BigDecimal(excel.getUsefulLife()));
            assetCard.setBuyDate(LocalDateTimeUtil.parseDate(excel.getBuyDate()));
            if (StrUtil.isNotEmpty(excel.getMaintenanceDate())) {
                assetCard.setMaintenanceDate(LocalDateTimeUtil.parseDate(excel.getBuyDate()));
            }
            // 名称转字典编码
            if (StrUtil.isEmpty(excel.getStatus())) {
                assetCard.setStatus(AssetCardConstant.ASSET_CARD_DEFAULT_STATUS);
            } else {
                assetCard.setStatus(DictItemResolver.getDictOptionValue(resultMap.get(AssetCardConstant.ASSET_STATUS), excel.getStatus()));
            }
            if (StrUtil.isEmpty(excel.getSource())) {
                assetCard.setSource(AssetCardConstant.ASSET_CARD_DEFAULT_SOURCE);
            } else {
                assetCard.setSource(DictItemResolver.getDictOptionValue(resultMap.get(AssetCardConstant.ASSET_SOURCE), excel.getStatus()));
            }
            // monetaryUnit
            assetCard.setMonetaryUnit((StrUtil.isEmpty(excel.getMonetaryUnit()) ? AssetCardConstant.ASSET_CARD_DEFAULT_MONETARY_UNIT : excel.getMonetaryUnit()));

            /**
             * 必填项{ctiCode:资产类型编码，belongept:所属单位}
             */
            Optional<AssetCti> ctiOptional = ctiList.stream().filter(cti -> cti.getCode().equals(excel.getCtiCode())).findFirst();
            if (ctiOptional.isPresent()) {
                AssetCti cti = ctiOptional.get();
                assetCard.setCtiId(cti.getId());
                assetCard.setCtiName(cti.getName());
                assetCard.setClassifiedCode(cti.getFullcode());
                assetCard.setClassified(cti.getFullname());
            } else {
                errorMsg.add(String.format("资产编码不存在：[%s] ", excel.getCtiCode()));
            }

            Optional<SysDept> deptOptional = deptList.stream().filter(dept -> dept.getFullName().equals(excel.getBelongdept())).findFirst();
            if (deptOptional.isPresent()) {
                SysDept sysDept = deptOptional.get();
                assetCard.setBelongdeptId(sysDept.getDeptId());
                assetCard.setBelongdept(sysDept.getName());
                assetCard.setBelongdeptFullname(sysDept.getFullName());
            } else {
                errorMsg.add(String.format("所属单位不存在：[%s] ", excel.getBelongdept()));
            }
            /**
             * 非必填项 使用单位：usedept ,使用人：useName,存放地点：locationCode,supplier：供应商。
             */
            Optional<SysDept> useDeptOptional = deptList.stream().filter(dept -> dept.getFullName().equals(excel.getUsedept())).findFirst();
            if (useDeptOptional.isPresent()) {
                SysDept sysDept = useDeptOptional.get();
                assetCard.setBelongdeptId(sysDept.getDeptId());
                assetCard.setBelongdept(sysDept.getName());
                assetCard.setBelongdeptFullname(sysDept.getFullName());
            }

            Optional<SysUser> userOptional = userList.stream().filter(user -> user.getUsername().equals(excel.getUseName())).findFirst();
            if (userOptional.isPresent()) {
                SysUser sysUser = userOptional.get();
                assetCard.setUseId(sysUser.getDeptId());
                assetCard.setUseName(sysUser.getDeptName());
            }

            Optional<AssetSupplier> supplierOptional = supplierList.stream().filter(supplier -> "V".equals(supplier.getType()) && supplier.getName().equals(excel.getSupplier())).findFirst();
            if (supplierOptional.isPresent()) {
                AssetSupplier fyAssetSupplier = supplierOptional.get();
                assetCard.setSupplierId(fyAssetSupplier.getId());
                assetCard.setSupplier(fyAssetSupplier.getName());
            }
            Optional<PositionVO> positionOptional = positionVOList.stream().filter(positionVO -> positionVO.getCode().equals(excel.getLocationCode())).findFirst();
            if (positionOptional.isPresent()) {
                PositionVO positionVO = positionOptional.get();
                assetCard.setLocationId(positionVO.getId());
                assetCard.setLocation(positionVO.getName());
                assetCard.setLocationType(positionVO.getTypeName());
            }

            // 数据合法情况
            if (CollUtil.isEmpty(errorMsg)) {
                this.save(assetCard);
            } else {
                // 数据不合法情况
                errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
            }
        }
        if (CollUtil.isNotEmpty(errorMessageList)) {
            return R.failed(errorMessageList);
        }
        return R.ok();
    }

    @Override
    public AssetCardCreateDTO create() {
        CloudUser user = SecurityUtils.getUser();
        BigDecimal bigDecimal = new BigDecimal(0);
        return AssetCardCreateDTO.builder()
                .buyDate(LocalDate.now())
                .useId(user.getId())
                .useName(user.getName())
                .usedeptId(user.getDeptId())
                .usedept(user.getFullName())
                .belongdeptId(user.getDeptId())
                .belongdept(user.getFullName())
                .belongdeptFullname(user.getFullName())
                .usedeptFullname(user.getFullName())
                .name(StrUtil.EMPTY)
                .model(StrUtil.EMPTY)
                .unid(UUID.randomUUID().toString())
                .unit(StrUtil.EMPTY)
                .originalAmount(bigDecimal)
                .source(AssetCardConstant.ASSET_CARD_DEFAULT_SOURCE)
                .monetaryUnit(AssetCardConstant.ASSET_CARD_DEFAULT_MONETARY_UNIT)
                .status(AssetCardConstant.ASSET_CARD_DEFAULT_STATUS)
                .fixedAssets(AssetCardConstant.ASSET_CARD_DEFAULT_FIXED_ASSETS)
                .build();
    }

    @Override
    public IPage<AssetCardDTO> getAssetCardPage(Page page, QueryWrapper<AssetCard> query) {
        query.notIn("status",CardStatusEnum.OFFSET.getCode());
        Page<AssetCard> curPage = super.baseMapper.selectPage(page, query);
        Page<AssetCardDTO> resultPage = new Page(curPage.getCurrent(), curPage.getSize(), curPage.getTotal());
        List<AssetCard> records = curPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            resultPage.setRecords(records.stream().map(r -> {
                AssetCardDTO assetCardDTO = new AssetCardDTO();
                BeanUtil.copyProperties(r, assetCardDTO);
                assetCardDTO.setSauId(r.getSauId());
                assetCardDTO.setAssetCardId(r.getId());
                return assetCardDTO;
            }).collect(Collectors.toList()));
        }
        return resultPage;
    }

    @Override
    public boolean updateStatus(List<Long> ids, String status) {
        LambdaQueryWrapper<AssetCard> queryWrapper = Wrappers.<AssetCard>query().lambda().in(BaseEntity::getId, ids);
        List<AssetCard> assetCardList = this.list(queryWrapper);
        if (CollUtil.isNotEmpty(assetCardList)) {
            assetCardList.forEach(card -> {
                card.setStatus(status);
                // 保存修改记录
                assetAssetUpdateService.save(card);
            });
            return this.saveOrUpdateBatch(assetCardList);
        }
        return false;
    }

    @Transactional
    @Override
    public List<AssetCard> generateByAssetCardList(AssetAc assetAc) {
        List<AssetCard> assetCardList = Lists.newArrayList();
        List<AssetAcList> acList = assetAc.getAcList();
        Iterator<AssetAcList> iterator = acList.iterator();
        while (iterator.hasNext()) {
            AssetAcList assetAcList = iterator.next();
            for (int i = 0; i < assetAcList.getQuantity(); i++) {
                assetCardList.add(generateByAssetCard(assetAc, assetAcList));
            }
        }
        boolean saveOrUpdateBatch = this.saveOrUpdateBatch(assetCardList);
        if(saveOrUpdateBatch){
            log.info("生成资产信息成功：时间：" + DateUtil.now());
        }
        return assetCardList;
    }

    @Override
    public R batchDelete(List<Long> ids) {
        int count = this.baseMapper.deleteBatchIds(ids);
        if (count > 0) {
            return R.ok(CommonConstants.SUCCESS, String.format("成功删除%s条数据", ids.size()));
        }
        return R.failed("删除失败");
    }

    @Override
    public AssetCardEditDTO edit(Long id) {
        AssetCard assetCard = this.getById(id);
        Assert.isTrue(ObjectUtils.isNotEmpty(assetCard), String.format("未找到对应的资产信息业务id为==>%s", id));
        AssetCardEditDTO editDTO = new AssetCardEditDTO();
        BeanUtil.copyProperties(assetCard,editDTO);
        return editDTO;
    }

    // 构建资产对象
    private AssetCard generateByAssetCard(AssetAc assetAc, AssetAcList assetAcList) {
        CloudUser user = SecurityUtils.getUser();
        AssetCard assetCard = new AssetCard();
        // 房间、位置、合同、供应商信息
        assetCard.setHouseId(assetAc.getHouseId());
        assetCard.setHouseName(assetAc.getHouseName());
        assetCard.setLocationId(assetAc.getLocationId());
        assetCard.setLocation(assetAc.getLocationName());
        assetCard.setParentStorageplace(assetAc.getFullLocation());
        assetCard.setContractId(assetAc.getContractId());
        assetCard.setContractNumber(assetAc.getContractNumber());
        assetCard.setSupplierId(assetAc.getSupplierId());
        assetCard.setSupplier(assetAc.getSupplierName());

        assetCard.setBelongdeptId(user.getDeptId());
        assetCard.setBelongdept(user.getName());
        assetCard.setBelongdeptFullname(user.getFullName());
        assetCard.setUsefulLife(AssetCardConstant.ASSET_CARD_DEFAULT_USEFULLIFE);
        // 供应商
        if (ObjectUtil.isNotEmpty(assetAc.getSupplierId()) && assetAc.getSupplierId() > 0) {
            AssetSupplier supplier = this.supplierService.getById(assetAc.getSupplierId());
            assetCard.setSupplierUser(supplier.getContactor());
            assetCard.setSupplierPhone(supplier.getContactTelephone());
        }
        // 基本信息
        assetCard.setCtiId(assetAcList.getCtiId());
        assetCard.setCtiName(assetAcList.getCtiName());
        assetCard.setClassified(assetAcList.getClassified());
        assetCard.setClassifiedCode(assetAcList.getClassifiedCode());
        AssetCti assetCti = fyAssetCtiService.getById(assetAcList.getCtiId());
        assetCard.setCtiType(assetCti.getAssetType());

        assetCard.setName(assetAcList.getName());
        assetCard.setNumber(assetAcList.getNumber());
        assetCard.setModel(assetAcList.getModel());
        assetCard.setSauId(assetAcList.getSauId());
        AssetSau sau = fyAssetSauService.getById(assetAcList.getSauId());
        assetCard.setSauName(sau.getName());
        assetCard.setUnid(UUID.randomUUID().toString());
        // TODO： 是否需要上传标准型号图片给资产信息
        assetCard.setPhoto(assetAcList.getPhoto());
        assetCard.setUnit(assetAcList.getUnit());
        assetCard.setOriginalAmount(assetAcList.getPrice());
        assetCard.setAmount(assetAcList.getPrice());
        assetCard.setStatus(CardStatusEnum.STOCK.getCode());
        assetCard.setPurchaseMode(assetAc.getMethod());
        assetCard.setMonetaryUnit(assetAc.getCurrencyType());
        assetCard.setSource(AssetCardConstant.ASSET_CARD_DEFAULT_SOURCE);
        assetCard.setFixedAssets(AssetCardConstant.ASSET_CARD_DEFAULT_FIXED_ASSETS);
        // 生命周期时间
        assetCard.setBuyDate(LocalDate.now());
        assetCard.setRecordDate(LocalDate.now());
        // 处理资产关联信息补充名称
        setFieldValue(assetCard);
        return assetCard;
    }

    /**
     * 资产一级分类的编码加上年度月度在加5位唯一码
     *
     * @param entity 资产信息
     */
    private void setFieldValue(AssetCard entity) {
        // 父级
        if (ObjectUtils.isNotEmpty(entity.getParentId()) && entity.getParentId() > 0) {
            AssetCard parentAssetCard = this.getById(entity.getParentId());
            entity.setParentName(parentAssetCard.getName());
            entity.setParentNumber(parentAssetCard.getNumber());
        }
        if (ObjectUtils.isNotEmpty(entity.getCtiId()) && entity.getCtiId() > 0) {
            AssetCti cti = this.fyAssetCtiService.getById(entity.getCtiId());
            entity.setCtiId(cti.getId());
            entity.setCtiName(cti.getName());
            entity.setCtiType(cti.getAssetType());
            entity.setClassified(cti.getFullname());
            entity.setClassifiedCode(cti.getFullcode());
        }
        if (ObjectUtils.isNotEmpty(entity.getSauId()) && entity.getSauId() > 0) {
            AssetSau sau = this.fyAssetSauService.getById(entity.getSauId());
            entity.setBarcode(sau.getBarcode());
            entity.setSauName(sau.getName());
        }
        // 所属单位
        if (ObjectUtils.isNotEmpty(entity.getBelongdeptId()) && entity.getBelongdeptId() > 0) {
            SysDept dept = remoteDeptService.getById(entity.getBelongdeptId()).getData();
            entity.setBelongdept(dept.getName());
            entity.setBelongdeptFullname(dept.getFullName());
        }
        // 使用单位
        if (ObjectUtils.isNotEmpty(entity.getUsedeptId()) && entity.getUsedeptId() > 0) {
            SysDept dept = remoteDeptService.getById(entity.getUsedeptId()).getData();
            entity.setUsedept(dept.getName());
            entity.setUsedeptFullname(dept.getFullName());
        }
        // 资产编码
        if (StrUtil.isEmpty(entity.getNumber())) {
            AssetCti cti = fyAssetCtiService.getById(entity.getCtiId());
            entity.setNumber(getNumberStr(cti, entity));
        }
    }

    /**
     * 获取资产编号
     *
     * @param cti    资产分类对象
     * @param entity 资产对象
     * @return 编号
     */
    private String getNumberStr(AssetCti cti, AssetCard entity) {
        StringBuilder typeCode = new StringBuilder();
        if (ObjectUtils.isNotEmpty(cti)) {
            entity.setCtiName(cti.getName());
            entity.setClassified(cti.getFullname());
            entity.setClassifiedCode(cti.getFullcode());
            typeCode.append(cti.getFullcode()).append(".");
        }
        typeCode.append(DateUtil.format(new Date(), "yyyyMM"));
        Long value = NumberResolver.getNumberValue(AssetCardConstant.ASSETS_NUMBER_TYPE, AssetCardConstant.ASSETS_NUMBER_CODE).getData();
        String formatStr = String.format("%05d", value);
        typeCode.append(formatStr);
        return typeCode.toString();
    }
}
